# 微信小程序图片缓存策略
后端更换了CDN上的图片,但是打开小程序,还是旧图片,尝试过删除小程序、在阿里云CDN控制台刷新缓存,重新进,还是旧图片。
因为图片文件名没改,请求地址没变,被客户端缓存了。
解决方法:
改文件名。但是图片名称都是按商品类目名称批量生成的,而且如果改文件名,要改代码
在图片地址后面加查询字符串嘛,哪张图片变了,就把它地址后面的查询字符串改一下,比如
?v=1
、?v=2
,但是还是要改代码,每次图片变了,得改小程序里引用这张图片地址后面的查询字符串,这还要重新发布。直接在图片地址后面生成时间戳不就好了,如:
${url}?ts=${new Date().getTime()}
。但是这样图片每次都会重新请求,性能会产生问题。
那为什么图片会被缓存?怎样才能让缓存失效?
打开控制台看下请求,如下:
从控制台里可以看到,图片响应是from disk cache
,说明图片资源被缓存到磁盘了,disk cache
是强缓存,它是持久存储。但是disk cache
是会严格根据HTTP
头信息中的缓存控制字段来判定哪些资源可以缓存,缓存多久的。我们可以在HTTP
响应头里设置Cache-Control
或Expires
来告诉小程序,这个图片应不应该被缓存,如果缓存,应该缓存多久。
可以看到,上图中,我的图片响应头里是没有Cache-Control
和Expires
的,所以当你没有在响应头里设置缓存策略时,小程序会强缓存你的图片,而且会缓存很久;
给这个图片的响应头加上Cache-Control: max-age=86400
,max-age
以秒为单位,86400
即24小时
。
这样设置以后,用户第一次访问图片会被小程序缓存,24小时内用户再次访问此图片,小程序不会发出网络请求,而是直接从磁盘缓存里读取。24小时以后,缓存过期,用户再次访问此图片时,小程序会发出请求从服务器获取最新图片。
如果图片是放在阿里云上的,应该如何设置响应头呢?
虽然图片是从CDN请求,但是我们CDN源站设置的是阿里云对象存储OSS的Bucket
域名,对象存储OSS可以设置资源的HTTP
响应头。
登录阿里云,进入对象存储OSS,找到资源所在Bucket
-文件管理,进入资源所在目录,资源列表右边“更多”里有“设置HTTP头“,除了可以设置单个资源的HTTP头,还可以选择当页所有资源,批量设置HTTP头。点击“设置HTTP头“,在“Cache-Control
"字段填上值保存就可以了,如下图:
除了刚才说的强缓存,还有一种协商缓存策略,再看之前响应的图,响应头里虽然没有Cache-Control
和Expires
,但是有ETag
和Last-Modified
,上面说当disk cache
过期后,小程序会重新向服务端发起请求,此时客户端会在请求头带着上一次图片响应的ETag
和Last-Modified
,分别放在If-None-Match
和If-Modified-Since
里,服务器接受到这两个字段后,会和当前资源比较,如果ETag
变了,或者资源修改时间大于上次修改时间,将返回新资源,否则返回304
告诉客户端,资源没有变化。